#ifndef FS_H
#define FS_H
#include <sys/stat.h>
#include "fs/file.h"
#include "tools/list.h"
#include "ipc/mutex.h"
#include "fs/fatfs/fatfs.h"
#include "applib/lib_syscall.h"

struct stat;
struct _fs_op_t;
struct _fs_t;

#define FS_MOUNT_POINT_SIZE 512

// 文件系统持有的回调函数表
typedef struct _fs_op_t
{
    int (*mount)(struct _fs_t * fs, int major, int minor);      // 挂载文件系统
    void (*unmount)(struct _fs_t * fs);                         // 取消挂载
    int (*open)(struct _fs_t * fs, const char * path, file_t * file);
    int (*read)(char * buff, int size, file_t * file);
    int (*write)(char * buff, int size, file_t * file);
    void (*close)(file_t * file);
    int (*seek)(file_t * file, uint32_t offset, int dir);
    int (*stat)(file_t * file, struct stat * st);
    int (*ioctl)(file_t * file, int cmd, int arg0, int arg1);

    int (*opendir)(struct _fs_t * fs, const char * name, DIR * dir);
    int (*readdir)(struct _fs_t * fs, DIR * dir, struct dirent * dirent);
    int (*closedir)(struct _fs_t * fs, DIR * dir);
    int (*unlink)(struct _fs_t * fs, const char * name);
}fs_op_t;


typedef enum _fs_type_t
{
    FS_DEVFS,
    FS_FAT16
}fs_type_t;


// 抽象文件系统
typedef struct _fs_t
{
    fs_op_t * op;                               // 回调函数表
    fs_type_t type;
    char mount_point[FS_MOUNT_POINT_SIZE];         // 挂载点
    void * data;
    int dev_id;
    list_node_t node;
    mutex_t * mutex;

    union 
    {
        fat_t fat_data;
    };
}fs_t;


const char * path_next_child(const char * path);
int path_to_num(const char * path, int * num); 

int sys_open(const char * name, int flags, ...);
int sys_read(int file, char * ptr, int len);
int sys_write(int file, char * ptr, int len);
// 移动文件指针
int sys_lseek(int file, int ptr, int dir);
int sys_close(int file);
int sys_isatty(int file);
int sys_fstat(int file, struct stat *st);
int sys_ioctl(int file, int cmd, int arg0, int arg1);
int sys_dup(int file);
void fs_init(void);

// 文件系统展示相关
int sys_opendir(const char * path, DIR * dir);
int sys_readdir(DIR * dir, struct dirent * dirent);
int sys_closedir(DIR * dir);  
int sys_unlink(const char * name);
#endif // !FS_H